package com.jt.www.job.issue;

import com.jt.www.admin.user.service.UserService;
import com.jt.www.common.service.JobQueryListService;
import com.jt.www.common.service.SendEmailsService;
import com.jt.www.dao.mapper.issue.mapper.IssuePolicyLogEntityMapper;
import com.jt.www.enums.ErrorCode;
import com.jt.www.enums.issue.PolicyEnum;
import com.jt.www.enums.issue.PolicyInterfaceEnum;
import com.jt.www.model.entity.User;
import com.jt.www.model.issue.entity.IssuePolicyLogEntity;
import com.jt.www.model.mail.dto.MailDTO;
import com.jt.www.model.param.endorse.AppDetailProParam;
import com.jt.www.model.pay.ResBindDetailQo;
import com.jt.www.model.pay.ResBindQo;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.vo.endorse.AppDetailProVo;
import com.jt.www.model.vo.sdCheck.AttachmentForProVO;
import com.jt.www.model.vo.sdCheck.HolderForProVO;
import com.jt.www.queue.systemparametes.ConfigurationParameters;
import com.jt.www.remote.DexClient;
import com.jt.www.remote.ins.InsClient;
import com.jt.www.util.DateUtils;
import com.jt.www.util.JsonUtils;
import com.jt.www.util.MD5Utils;
import com.jt.www.util.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.util.StringUtil;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.net.URLDecoder;
import java.util.*;


/**
 * 下载发票的任务
 */
@Component
@EnableScheduling
public class CheckDownInvoiceTask implements SchedulingConfigurer {

    public static final Logger log = LoggerFactory.getLogger(CheckDownInvoiceTask.class);
    /**
     * 单个服务器出单查询缓存失效时间 因不同的定时任务决定
     */
    private static final long DOWN_INVOICE_TIME_OUT = 80L;
    /**
     * 检查下载发票的任务 缓存key
     */
    private static final String DOWN_INVOICE_LOCK_KEY = "EDU_DOWN_INVOICE";
    @Autowired
    IssuePolicyLogEntityMapper issuePolicyLogEntityMapper;
    @Autowired
    JobQueryListService jobQueryListService;
    @Autowired
    InsClient insClient;
    @Autowired
    DexClient dexClient;
    @Autowired
    SendEmailsService emailsService;
    @Autowired
    UserService userService;
    @Autowired
    private ConfigurationParameters configurationParameters;
    //  任务开关
    @Value("${jtpf.downinvoice.open}")
    private int checkOpen;
    // 任务执行周期
    @Value("${jtpf.downinvoice.cron}")
    private String cron;// 每隔一分钟执行一次
    // 多长时间之前的  时间
    @Value("${jtpf.downinvoice.minute}")
    private int beforeTime;
    @Value("${jtpf.downinvoice.times}")
    private int times;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        if (checkOpen != 1) {
            return;
        }
        if (RedisUtil.setLock(DOWN_INVOICE_LOCK_KEY, "1", DOWN_INVOICE_TIME_OUT)) {
            Runnable task0 = () -> checkStart();
            Trigger trigger0 = triggerContext -> new CronTrigger(cron).nextExecutionTime(triggerContext);
            taskRegistrar.addTriggerTask(task0, trigger0);
        }
    }

    private void checkStart() {
        String currentTime = DateUtils.getCurrentTime();
        log.info(currentTime + "CheckAgreeExpireTask satrt,检查电子发票的任务开始...");
        // 第一步：查询未生成发票/生成发票失败的记录 t_issue_policy_log.status in (1,7)
        List<IssuePolicyLogEntity> issuePolicyLogEntities = checkInvoice();
        // 生成发票 (学责)
        createInvoice(issuePolicyLogEntities);

        // 第三步 看 学责发票 生成 但是没有下载和绑定的  20分钟之前的
        issuePolicyLogEntities = checkDownInvoice();
        // 学责 ：下载并绑定  发票
        downAndBind(issuePolicyLogEntities);

        // 第四步  实责和校责
        issuePolicyLogEntities = checkDownSZANDXZInvoice();
        downAndBindSZANDXZ(issuePolicyLogEntities);

       /* // 第5步   云南非九   todo
        issuePolicyLogEntities = checkDownYNFJInvoice();
        downAndBindYNFJ(issuePolicyLogEntities);*/

        // 第5步   云南非九诚泰   todo
        issuePolicyLogEntities = checkDownCTYNFJInvoice();
        downAndBindCTYNFJ(issuePolicyLogEntities);

        //食品险电子发票
        issuePolicyLogEntities = checkDownSPInvoice();
        downAndBindSP(issuePolicyLogEntities);

        //广东校责、食品、教职工、校车
        issuePolicyLogEntities = checkDownGDInvoice();
        downAndBindGD(issuePolicyLogEntities);

        log.info(currentTime + "CheckMessageConsumeFailTask end,检查电子发票的任务结束...");
    }


    /**
     * 云南非九诚泰下载电子发票
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBindCTYNFJ(List<IssuePolicyLogEntity> issuePolicyLogEntities) {

        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                log.info(DateUtils.getCurrentTime() + "job调用云南非九下载发票的接口，入参" + t.getParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                ResponseEntity<String> responseEntity = null;
                String ebody = null;
                try {
                    responseEntity = dexClient.text("", "202011031136360", "1.0", seqNo, t.getParam());
                    log.info(DateUtils.getCurrentTime() + "job调用云南非九下载发票的接口，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                    // 请求200，继续执行
                    if (responseEntity.getStatusCodeValue() != 200) {
                        log.error("云南非九请求下载电子发票失败");
                        t.setStatus("6");
                        t.setTimes(times);
                    } else {
                        ebody = responseEntity.getBody();
                        String fail = URLDecoder.decode(ebody, "UTF-8");
                        if (fail.contains(ErrorCode.SUCCESS_MSG)) {
                            t.setStatus("2");
                            t.setTimes(times);
                        } else {
                            log.error("投保单号:{},电子发票失败原因:{} ", issuePolicyLogEntities.get(0).getApplicationFormCode(), fail);
                            t.setStatus("6");
                            t.setTimes(times);
                        }
                    }
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }

    /**
     * 云南非九下载电子发票
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBindYNFJ(List<IssuePolicyLogEntity> issuePolicyLogEntities) {

        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                log.info(DateUtils.getCurrentTime() + "job调用云南非九下载发票的接口，入参" + t.getDownParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                ResponseEntity<String> responseEntity = null;
                try {
                    responseEntity = dexClient.text("", "20190516036", "1.0", seqNo, t.getDownParam());
                    log.info(DateUtils.getCurrentTime() + "job调用云南非九下载发票的接口，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                    // 请求200，继续执行
                    if (responseEntity.getStatusCodeValue() != 200) {
                        log.error("请求下载电子发票失败");
                        t.setStatus("6");
                        t.setTimes(times);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    } else {
                        String ebody = responseEntity.getBody();
                        Document doc = DocumentHelper.parseText(ebody);
                        Element ebodyElement = doc.getRootElement();
                        String code = ebodyElement.element("code").getStringValue();
                        if ("0000".equals(code)) {
                            String eInvoiceId = ebodyElement.element("data").getStringValue();
                            t.setStatus("2");
                            t.setEInvoiceId(eInvoiceId);
                            t.setTimes(times);
                            bindInvoice(t.getApplicationFormCode(), eInvoiceId, t);
                        } else {
                            t.setStatus("6");
                            t.setTimes(times);
                            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }

    /**
     * 实责校责下载电子发票
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBindSZANDXZ(List<IssuePolicyLogEntity> issuePolicyLogEntities) {
        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                String policyNo = t.getPolicyNo();
                int times = t.getTimes() + 1;
                log.info(DateUtils.getCurrentTime() + "job调用" + policyNo + "下载发票的接口，入参" + t.getParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                ResponseEntity<String> responseEntity = null;
                String invoiceParam = t.getParam();
                try {
                    //根据ifCode先申请发票
                    if (t.getIfCode().equals(PolicyInterfaceEnum.CODE_24.getIfCode())) {
                        log.info(DateUtils.getCurrentTime() + "投保单号是" + t.getApplicationFormCode() + "发票申请开始，入参" + t.getParam());
                        responseEntity = dexClient.text("edu", "202012091335240", "1.0", seqNo, t.getParam());
                        log.info(DateUtils.getCurrentTime() + "投保单号是" + t.getApplicationFormCode() + "发票申请结束，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                        if (responseEntity.getBody().equals("Effective")) {
                            //判断返回的是够是申请成功,如果开具成功Effective,自己拼接下载地址进行下载
                            String url = getGSInvoiceAddress(policyNo);
                            //根据地址下载电子发票
                            Map<String, String> invoiceMap = new HashMap<>();
                            invoiceMap.put("ApplicationFormCode", t.getApplicationFormCode());
                            invoiceMap.put("url", url);
                            invoiceParam = JsonUtils.toJson(invoiceMap);
                        }
                    }
                    String invoice = PolicyEnum.getPolicyOrInvoiceByIfCode(t.getIfCode(), "INVOICE");
                    responseEntity = dexClient.text("edu", invoice, "1.0", seqNo, invoiceParam);
                    log.info(DateUtils.getCurrentTime() + "job调用" + policyNo + "下载发票的接口，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                    if (StringUtil.isEmpty(responseEntity.getBody())) {
                        log.error("请求下载电子发票失败");
                        t.setStatus("6");
                        t.setTimes(times);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    } else {
                        if (responseEntity.getStatusCodeValue() != 200) {
                            log.error("请求下载电子发票失败");
                            t.setStatus("6");
                            t.setTimes(times);
                            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                        } else {
                            String ebody = responseEntity.getBody();
                            Document doc = DocumentHelper.parseText(ebody);
                            Element ebodyElement = doc.getRootElement();
                            String code = ebodyElement.element("code").getStringValue();
                            if ("0000".equals(code)) {
                                String eInvoiceId = ebodyElement.element("data").getStringValue();
                                t.setStatus("2");
                                t.setEInvoiceId(eInvoiceId);
                                t.setTimes(times);
                                bindInvoice(t.getApplicationFormCode(), eInvoiceId, t);
                            } else {
                                t.setStatus("6");
                                t.setTimes(times);
                                issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }


    //拼接国寿下载发票地址
    public String getGSInvoiceAddress(String policyNo) {
        String key = policyNo + "gpic@2018!";
        String sign = MD5Utils.MD5(key);
        String url = configurationParameters.getDownInvoiceUrl() + "sign=00" + "edu" + sign + "&PolicyNo=" + policyNo;
        return url;
    }

    /**
     * 食品险下载电子发票
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBindSP(List<IssuePolicyLogEntity> issuePolicyLogEntities) {
        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                log.info(DateUtils.getCurrentTime() + "job调用食品下载发票的接口，入参" + t.getParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                try {
                    ResponseEntity<String> responseEntity = null;
                    String param = t.getParam();
                    if (t.getIfCode().equals("20190909101")) {
                        responseEntity = dexClient.text("edu", "202012091335240", "1.0", seqNo, t.getParam());
                        log.info(DateUtils.getCurrentTime() + "投保单号是" + t.getApplicationFormCode() + "发票申请结束，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                        if (responseEntity.getBody().equals("Effective")) {
                            //判断返回的是够是申请成功,如果开具成功Effective,自己拼接下载地址进行下载
                            String url = getGSInvoiceAddress(t.getPolicyNo());
                            //根据地址下载电子发票
                            Map<String, String> invoiceMap = new HashMap<>();
                            invoiceMap.put("ApplicationFormCode", t.getApplicationFormCode());
                            invoiceMap.put("url", url);
                            param = JsonUtils.toJson(invoiceMap);
                            log.info("电子发票生成的地址为 {} ", param);
                        }
                    }
                    String invoice = PolicyEnum.getPolicyOrInvoiceByIfCode(t.getIfCode(), "INVOICE");
                    System.out.println("请求接口地址" + invoice);
                    responseEntity = dexClient.text("edu", invoice, "1.0", seqNo, param);
                    log.info(DateUtils.getCurrentTime() + "job调用食品下载发票的接口，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                    if (StringUtil.isNotEmpty(responseEntity.getBody())) {
                        String invoiceFileId = null;
                        if (t.getIfCode().equals("20190909101") || t.getIfCode().equals("20190802002")) {
                            String ebody = responseEntity.getBody();
                            Document doc = DocumentHelper.parseText(ebody);
                            Element ebodyElement = doc.getRootElement();
                            String code = ebodyElement.element("code").getStringValue();
                            if ("0000".equals(code)) {
                                invoiceFileId = ebodyElement.element("data").getStringValue();
                            }
                        } else {
                            invoiceFileId = responseEntity.getBody();
                        }
                        // 下载成功，更新数据库，绑定资源
                        log.info("阳光食品险 下载消息 invoiceFileId ：{}", invoiceFileId);
                        t.setStatus("2");
                        t.setTimes(times);
                        t.setEInvoiceId(invoiceFileId);
                        bindInvoice(t.getApplicationFormCode(), invoiceFileId, t);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    } else {
                        log.error("阳光食品险请求下载电子发票失败");
                        t.setStatus("6");
                        t.setTimes(times);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }

    /**
     * 学责下载电子发票
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBind(List<IssuePolicyLogEntity> issuePolicyLogEntities) {

        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                log.info(DateUtils.getCurrentTime() + "job调用数据交换中心下载发票开始，入参：" + t.getDownParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                ResponseEntity<String> responseEntity = null;
                try {
                    responseEntity = dexClient.text("edu", "20190515013", "1.1", seqNo, t.getDownParam());
                    log.info(DateUtils.getCurrentTime() + "job调用数据交换中心下载发票结束，回参：" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                    // 请求200，继续执行
                    if (responseEntity.getStatusCodeValue() != 200) {
                        log.error("请求下载电子发票失败");
                        t.setStatus("6");
                        t.setTimes(times);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    } else {
                        String ebody = responseEntity.getBody();
                        Document doc = DocumentHelper.parseText(ebody);
                        Element ebodyElement = doc.getRootElement();
                        String code = ebodyElement.element("code").getStringValue();
                        if ("0000".equals(code)) {
                            String eInvoiceId = ebodyElement.element("data").getStringValue();
                            t.setStatus("2");
                            t.setEInvoiceId(eInvoiceId);
                            t.setTimes(times);
                            bindInvoice(t.getApplicationFormCode(), eInvoiceId, t);
                        } else {
                            t.setStatus("6");
                            t.setTimes(times);
                            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }

    private void bindInvoice(String applicationFormCode, String fileId, IssuePolicyLogEntity issuePolicyLogEntity) throws Exception {
        String status = issuePolicyLogEntity.getStatus();
        ResBindQo resBindQo = new ResBindQo();
        resBindQo.setApplicationFormCode(applicationFormCode);
        ResBindDetailQo resBindDetailQo = new ResBindDetailQo();
        resBindDetailQo.setBizCodeType("02");
        resBindDetailQo.setResCode("P001");
        resBindDetailQo.setResId(fileId);
        resBindDetailQo.setResName("电子发票");
        List<ResBindDetailQo> list = new ArrayList<>();
        list.add(resBindDetailQo);
        resBindQo.setDetailList(list);
        ResponseEntity<GenericListResponse<Map<String, String>>> genericListResponseResponseEntity = null;
        genericListResponseResponseEntity = insClient.bindResources(resBindQo);
        GenericListResponse<Map<String, String>> body = genericListResponseResponseEntity.getBody();
        String code = body.getCode();
        log.info(DateUtils.getCurrentTime() + "调用绑定资源接口返回结果码" + code + ":" + body.getMsg());
        if (!"0000".equals(code)) {
            issuePolicyLogEntity.setEPolicyId(fileId);
            issuePolicyLogEntity.setStatus("6");
            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(issuePolicyLogEntity);
        } else {
            issuePolicyLogEntity.setEPolicyId(fileId);
            issuePolicyLogEntity.setStatus("2");
            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(issuePolicyLogEntity);
        }
    }

    private List<IssuePolicyLogEntity> checkDownYNFJInvoice() {

        // 时间20分钟之前的
        Calendar cal = Calendar.getInstance();
        Date date = new Date();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, -beforeTime);
        date = cal.getTime();
        String format = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");

        // 云南非九   状态6  type3  Procode = 40000
        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        criteria.andLessThan(IssuePolicyLogEntity::getCreateTime, format);

        List<String> productList = new ArrayList<String>();
        productList.add("19PR452292");//.add("40000");//校方综合防范保障保险
        productList.add("19PR467834");//.add("30000");//教职员工校方责任保险
        productList.add("19PR233356");//.add("20000");//校园食品安全责任保险
        productList.add("19PR534934");//.add("10000");//云南省校方责任保险

        criteria.andIn(IssuePolicyLogEntity::getProCode, productList);
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }


    private List<IssuePolicyLogEntity> checkDownCTYNFJInvoice() {
        // 云南非九   状态1或者6  type3  ifCode = 202010231517560
        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getIfCode, "202010231517560");
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }

    private List<IssuePolicyLogEntity> checkDownSZANDXZInvoice() {

        // 实责校责  状态6  type3  Procode = 1 或者 2 ；maintype 1或 2
        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        List<String> procodeList = new ArrayList<String>();
        procodeList.add("19PR789827");//.add("1");// 全国职业院校学生实习责任保险
        procodeList.add("19PR961660");//.add("2");// 校方责任保险
        criteria.andIn(IssuePolicyLogEntity::getProCode, procodeList);
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        //List<String> mainTypeList = new ArrayList<String>();
        //mainTypeList.add("1");// 实责
        //mainTypeList.add("2");// 校责
        //criteria.andIn(IssuePolicyLogEntity::getMainType, mainTypeList);

        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }


    private List<IssuePolicyLogEntity> checkDownSPInvoice() {

        // 食品险  状态6  type3  Procode = 1 或者 2 ；maintype 1或 2
        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        List<String> procodeList = new ArrayList<String>();
        procodeList.add("19PR701524"); // 食品险
        criteria.andIn(IssuePolicyLogEntity::getProCode, procodeList);
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }

    private List<IssuePolicyLogEntity> checkDownInvoice() {

        // 时间20分钟之前的
        Calendar cal = Calendar.getInstance();
        Date date = new Date();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, -beforeTime);
        date = cal.getTime();
        String format = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");

        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        //criteria.andEqualTo(IssuePolicyLogEntity::getProCode, "1");
        criteria.andEqualTo(IssuePolicyLogEntity::getProCode, "19PR403423");//学责
        //criteria.andEqualTo(IssuePolicyLogEntity::getMainType, "0");
        criteria.andLessThan(IssuePolicyLogEntity::getCreateTime, format);
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }

    private void createInvoice(List<IssuePolicyLogEntity> issuePolicyLogEntities) {
        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {

            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                // 只有学责，云南非九  需要生成发票
                String proCode = t.getProCode();
                //String mainType = t.getMainType();
                //if("1".equals(proCode) && "0".equals(mainType)){
                if ("19PR403423".equals(proCode)) {//学责
                    try {
                        // 生成发票
                        // 调接口  生成发票
                        log.info(DateUtils.getCurrentTime() + "job调用学责生成发票接口，入参" + t.getParam());
                        String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                        ResponseEntity<String> responseEntity = dexClient.text("edu", "20190515013", "1.0", seqNo, t.getParam());
                        String ebody = responseEntity.getBody();
                        log.info(DateUtils.getCurrentTime() + "job调用学责生成发票接口，回参" + ebody + "," + responseEntity.getStatusCodeValue());
                        Document doc = null;
                        doc = DocumentHelper.parseText(ebody);
                        Element ebodyElement = doc.getRootElement();
                        // 根据code 0000  判断 。也可以根据返回值data判断  成功有数据，失败为null
                        // String code = ebodyElement.element("code").getStringValue();
                        String code = ebodyElement.element("POLICY").attributeValue("RETURN");

                        if ("true".equals(code)) {
                            // 组装生成电子发票的报文
                            doc = DocumentHelper.createDocument();
                            Element info = doc.addElement("Message");
                            doc.setRootElement(info);
                            Element Body = info.addElement("Body");
                            // Element OrderNo = Body.addElement("OrderNo").addText(orderNo);
                            Element PolicyNO = Body.addElement("PolicyNO").addText(t.getPolicyNo());
                            t.setDownParam(info.asXML());
                            t.setStatus("6");
                            t.setTimes(times);
                            // 生成电子发票成功，更新数据库，
                            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                        } else {
                            log.error("请求生成电子保单失败");
                            t.setStatus("7");
                            t.setTimes(times);
                            // 生成电子发票失败，更新数据库，
                            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("请求生成电子保单失败");
                        t.setStatus("7");
                        t.setTimes(times);
                        // 生成电子发票失败，更新数据库，
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    }
                }
            }
        }
    }

    /**
     * 查询未生成发票/生成发票失败的记录 t_issue_policy_log.status in (1,7)
     *
     * @return
     */
    private List<IssuePolicyLogEntity> checkInvoice() {

        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        List<String> statusList = new ArrayList<String>();
        statusList.add("1");// 没有生成发票，
        statusList.add("7");// 生成发票失败的
        criteria.andIn(IssuePolicyLogEntity::getStatus, statusList);
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);

        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }

    /**
     * 广东校责、食品、教职工、校车
     *
     * @return
     */
    private List<IssuePolicyLogEntity> checkDownGDInvoice() {

        // 状态6  type3
        Weekend<IssuePolicyLogEntity> weekend = Weekend.of(IssuePolicyLogEntity.class);
        WeekendCriteria<IssuePolicyLogEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IssuePolicyLogEntity::getType, "3");
        criteria.andEqualTo(IssuePolicyLogEntity::getStatus, "6");
        List<String> procodeList = new ArrayList<String>();
        procodeList.add("20PR806488"); // 广东校责
        procodeList.add("20PR191668"); // 广东食品
        procodeList.add("20PR530654"); // 广东教职工
        procodeList.add("20PR485549"); // 广东校车
        criteria.andIn(IssuePolicyLogEntity::getProCode, procodeList);
        criteria.andLessThan(IssuePolicyLogEntity::getTimes, times);
        return jobQueryListService.getJobProcessIssuePolicyLogList(weekend);
    }

    /**
     * 广东校责、食品、教职工、校车
     *
     * @param issuePolicyLogEntities
     */
    private void downAndBindGD(List<IssuePolicyLogEntity> issuePolicyLogEntities) {
        String findCode = "downAndBindGD_" + System.currentTimeMillis();

        if (issuePolicyLogEntities != null && issuePolicyLogEntities.size() > 0) {
            for (IssuePolicyLogEntity t : issuePolicyLogEntities) {
                int times = t.getTimes() + 1;
                log.info("{} job调用广东太保下载发票的接口，入参{}", findCode, t.getParam());
                String seqNo = Long.toString(Math.abs(new Random().nextLong()));
                try {
                    ResponseEntity<String> responseEntity = dexClient.text("edu", "202009031726310", "1.0", seqNo, t.getParam());
                    log.info("{} job调用广东太保下载发票的接口，回参{},{}", findCode, responseEntity.getStatusCodeValue(), responseEntity.getBody());
                    if (StringUtil.isNotEmpty(responseEntity.getBody())) {
                        String invoiceFileId = responseEntity.getBody();
                        // 下载成功，更新数据库，绑定资源
                        log.info("{} job调用广东太保下载发票的接口 下载消息 invoiceFileId ：{}", findCode, invoiceFileId);
                        t.setStatus("2");
                        t.setTimes(1);
                        t.setEPolicyId(invoiceFileId);
                        bindInvoice(t.getApplicationFormCode(), invoiceFileId, t);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);

                        sendInvoiceEmailGD(findCode, t.getApplicationFormCode(), "23");
                    } else {
                        log.info("{} job调用广东太保下载发票的接口 下载失败", findCode);
                        t.setStatus("6");
                        t.setTimes(times);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("{} job调用广东太保下载发票的接口 请求下载电子发票异常", findCode);
                    t.setStatus("6");
                    t.setTimes(times);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
        }
    }


    /**
     * 广东4款产品发送电子发票邮件
     *
     * @param tbNo
     * @param type
     */
    private void sendInvoiceEmailGD(String findCode, String tbNo, String type) {
        log.info("{} 广东4款产品发送电子发票邮件 投保单号：{}，type：{}", findCode, tbNo, type);
        AppDetailProVo detailVos = null;
        ResponseEntity<GenericDataResponse<AppDetailProVo>> appDetailPro;
        AppDetailProParam p = new AppDetailProParam();
        p.setAppCode(tbNo);
        p.setChannelCode("edu");    // 渠道编号
        try {
            appDetailPro = insClient.searchAppDetailPro(p);
            detailVos = appDetailPro.getBody().getData();
            MailDTO mailDTO = new MailDTO();
            HolderForProVO holder = detailVos.getHolder();
            String holderCode = holder.getHolderCode();
            User userholder = userService.findEduUserByCode(holderCode);
            mailDTO.setUserName(userholder.getName());
            mailDTO.setProductName(detailVos.getProductName());
            mailDTO.setEmail(userholder.getEmail());
            mailDTO.setProposalNo(detailVos.getPolicyNo());
            mailDTO.setOrderNo(detailVos.getOrderCode());
            mailDTO.setPolicyNo(Collections.singletonList(tbNo));

            log.info("{} 广东4款产品发送电子发票邮件 投保单号：{}，邮件内容：{}", findCode, tbNo, mailDTO);

            List<AttachmentForProVO> appAttachmentList = detailVos.getAppAttachmentList();
            for (AttachmentForProVO attachment : appAttachmentList) {
                if ("P001".equals(attachment.getResCode())) {
                    log.info("{} 广东4款产品发送电子发票邮件 投保单号：{}，下载地址：{}", findCode, tbNo, attachment.getFileUrl());
                    mailDTO.setPolicyId(attachment.getFileUrl());
                }
            }

            if (!StringUtils.isEmpty(userholder.getEmail())) {
                emailsService.sendEmail(mailDTO, type);
            }
        } catch (Exception e) {
            log.error("{} 广东4款产品发送电子发票邮件 根据投保单号 {} 查询投保单信息失败，异常信息：{}", findCode, tbNo, e);
        }

        log.info("{} 广东4款产品发送电子发票邮件 投保单号：{} 邮件发送完成", findCode, tbNo);

    }
}
